package com.caseprocessing.controller;

import com.caseprocessing.model.*;
import com.caseprocessing.service.*;
import java.util.*;

/**
 * 案卷处理主控制器
 * 负责协调整个文书处理流程
 */
public class CaseProcessingController {
    
    private MetadataExtractor metadataExtractor;
    private DocumentSplitter documentSplitter;
    private DocumentClassifier documentClassifier;
    private ComplianceChecker complianceChecker;
    
    public CaseProcessingController() {
        this.metadataExtractor = new MetadataExtractor();
        this.documentSplitter = new DocumentSplitter();
        this.documentClassifier = new DocumentClassifier();
        this.complianceChecker = new ComplianceChecker();
    }
    
    /**
     * 主处理方法 - 完整的案卷处理流程
     */
    public CaseProcessingResult processCase(CaseDocument caseDocument) {
        CaseProcessingResult result = new CaseProcessingResult();
        result.setCaseId(caseDocument.getCaseId());
        result.setProcessingStartTime(getCurrentTimestamp());
        
        try {
            // 阶段一：文档预分析和元数据提取
            System.out.println("开始阶段一：文档预分析和元数据提取...");
            DocumentMetadata metadata = metadataExtractor.extractMetadata(caseDocument);
            caseDocument.setMetadata(metadata);
            result.setMetadata(metadata);
            
            // 阶段二：智能文档分割
            System.out.println("开始阶段二：智能文档分割...");
            List<DocumentSegment> segments = documentSplitter.splitDocument(caseDocument);
            result.setSegments(segments);
            
            // 阶段三：文书类型分类
            System.out.println("开始阶段三：文书类型分类...");
            List<DocumentSegment> classifiedSegments = documentClassifier.classifyAll(segments);
            result.setSegments(classifiedSegments);
            
            // 阶段四：合规性检查
            System.out.println("开始阶段四：合规性检查...");
            List<ComplianceResult> complianceResults = complianceChecker.checkAllDocuments(classifiedSegments);
            result.setComplianceResults(complianceResults);
            
            // 生成处理报告
            ProcessingReport report = generateProcessingReport(result);
            result.setProcessingReport(report);
            
            // 设置处理状态
            result.setProcessingStatus(ProcessingStatus.COMPLETED);
            result.setOverallSuccess(true);
            
        } catch (Exception e) {
            // 处理异常情况
            handleProcessingException(result, e);
        } finally {
            result.setProcessingEndTime(getCurrentTimestamp());
            result.setProcessingDuration(calculateDuration(result.getProcessingStartTime(), 
                                                          result.getProcessingEndTime()));
        }
        
        return result;
    }
    
    /**
     * 生成处理报告
     */
    private ProcessingReport generateProcessingReport(CaseProcessingResult result) {
        ProcessingReport report = new ProcessingReport();
        
        // 基本统计信息
        report.setTotalPages(result.getMetadata() != null ? 
                           result.getMetadata().getProcessingInfo().getProcessingDuration() : 0);
        report.setTotalSegments(result.getSegments().size());
        
        // 分类统计
        Map<DocumentType, Integer> classificationStats = documentClassifier.getClassificationStatistics(result.getSegments());
        report.setClassificationStatistics(classificationStats);
        
        // 合规性统计
        ComplianceReport complianceReport = complianceChecker.generateReport(result.getComplianceResults());
        report.setComplianceReport(complianceReport);
        
        // 质量评估
        QualityAssessment quality = assessProcessingQuality(result);
        report.setQualityAssessment(quality);
        
        // 异常和警告汇总
        List<ProcessingException> exceptions = collectExceptions(result);
        report.setExceptions(exceptions);
        
        return report;
    }
    
    /**
     * 评估处理质量
     */
    private QualityAssessment assessProcessingQuality(CaseProcessingResult result) {
        QualityAssessment assessment = new QualityAssessment();
        
        // 计算分割质量评分
        double splittingQuality = calculateSplittingQuality(result.getSegments());
        assessment.setSplittingQuality(splittingQuality);
        
        // 计算分类质量评分
        double classificationQuality = calculateClassificationQuality(result.getSegments());
        assessment.setClassificationQuality(classificationQuality);
        
        // 计算合规性评分
        double complianceQuality = calculateComplianceQuality(result.getComplianceResults());
        assessment.setComplianceQuality(complianceQuality);
        
        // 计算整体评分
        double overallScore = (splittingQuality + classificationQuality + complianceQuality) / 3.0;
        assessment.setOverallScore(overallScore);
        
        // 确定质量等级
        assessment.setQualityLevel(determineQualityLevel(overallScore));
        
        return assessment;
    }
    
    /**
     * 计算分割质量评分
     */
    private double calculateSplittingQuality(List<DocumentSegment> segments) {
        if (segments.isEmpty()) return 0.0;
        
        double totalConfidence = 0.0;
        int validSegments = 0;
        
        for (DocumentSegment segment : segments) {
            if (segment.isValid()) {
                totalConfidence += segment.getConfidence();
                validSegments++;
            }
        }
        
        return validSegments > 0 ? totalConfidence / validSegments : 0.0;
    }
    
    /**
     * 计算分类质量评分
     */
    private double calculateClassificationQuality(List<DocumentSegment> segments) {
        if (segments.isEmpty()) return 0.0;
        
        int classifiedSegments = 0;
        double totalClassificationConfidence = 0.0;
        
        for (DocumentSegment segment : segments) {
            if (segment.getDocumentType() != null && segment.getDocumentType() != DocumentType.OTHER) {
                classifiedSegments++;
                totalClassificationConfidence += segment.getConfidence();
            }
        }
        
        return classifiedSegments > 0 ? totalClassificationConfidence / classifiedSegments : 0.0;
    }
    
    /**
     * 计算合规性评分
     */
    private double calculateComplianceQuality(List<ComplianceResult> results) {
        if (results.isEmpty()) return 0.0;
        
        int passedCount = 0;
        int warningCount = 0;
        
        for (ComplianceResult result : results) {
            if (result.getOverallStatus() == CheckStatus.PASSED) {
                passedCount++;
            } else if (result.getOverallStatus() == CheckStatus.WARNING) {
                warningCount++;
            }
        }
        
        // 通过的得1分，警告的得0.5分，失败的得0分
        return (double) (passedCount + warningCount * 0.5) / results.size();
    }
    
    /**
     * 确定质量等级
     */
    private QualityLevel determineQualityLevel(double score) {
        if (score >= 0.9) return QualityLevel.EXCELLENT;
        if (score >= 0.8) return QualityLevel.GOOD;
        if (score >= 0.6) return QualityLevel.ACCEPTABLE;
        if (score >= 0.4) return QualityLevel.POOR;
        return QualityLevel.UNACCEPTABLE;
    }
    
    /**
     * 收集处理异常
     */
    private List<ProcessingException> collectExceptions(CaseProcessingResult result) {
        List<ProcessingException> exceptions = new ArrayList<>();
        
        // 检查元数据问题
        if (result.getMetadata() != null) {
            CompletenessCheck completeness = result.getMetadata().getCompletenessCheck();
            if (completeness != null) {
                if (!completeness.isPageNumberContinuity()) {
                    exceptions.add(new ProcessingException("METADATA_ISSUE", 
                        "页码不连续", ProcessingException.Severity.MEDIUM));
                }
                
                if (!completeness.isDirectoryIntegrity()) {
                    exceptions.add(new ProcessingException("METADATA_ISSUE", 
                        "目录完整性问题", ProcessingException.Severity.MEDIUM));
                }
            }
        }
        
        // 检查分割问题
        boolean hasLowConfidenceSegments = result.getSegments().stream()
            .anyMatch(segment -> segment.getConfidence() < 0.5);
        
        if (hasLowConfidenceSegments) {
            exceptions.add(new ProcessingException("SPLITTING_ISSUE", 
                "存在低置信度的文档分割", ProcessingException.Severity.MEDIUM));
        }
        
        // 检查分类问题
        long unclassifiedCount = result.getSegments().stream()
            .filter(segment -> segment.getDocumentType() == DocumentType.OTHER)
            .count();
        
        if (unclassifiedCount > result.getSegments().size() * 0.3) {
            exceptions.add(new ProcessingException("CLASSIFICATION_ISSUE", 
                "大量文档未能正确分类", ProcessingException.Severity.HIGH));
        }
        
        // 检查合规性问题
        long failedComplianceCount = result.getComplianceResults().stream()
            .filter(compliance -> compliance.getOverallStatus() == CheckStatus.FAILED)
            .count();
        
        if (failedComplianceCount > 0) {
            exceptions.add(new ProcessingException("COMPLIANCE_ISSUE", 
                failedComplianceCount + "个文档存在合规性问题", ProcessingException.Severity.HIGH));
        }
        
        return exceptions;
    }
    
    /**
     * 处理异常情况
     */
    private void handleProcessingException(CaseProcessingResult result, Exception e) {
        result.setProcessingStatus(ProcessingStatus.FAILED);
        result.setOverallSuccess(false);
        result.setErrorMessage(e.getMessage());
        
        ProcessingException exception = new ProcessingException("PROCESSING_ERROR", 
            "处理过程中发生异常: " + e.getMessage(), ProcessingException.Severity.CRITICAL);
        
        result.setExceptions(Arrays.asList(exception));
        
        System.err.println("案卷处理失败: " + e.getMessage());
        e.printStackTrace();
    }
    
    /**
     * 获取当前时间戳
     */
    private String getCurrentTimestamp() {
        return String.valueOf(System.currentTimeMillis());
    }
    
    /**
     * 计算处理耗时
     */
    private long calculateDuration(String startTime, String endTime) {
        try {
            long start = Long.parseLong(startTime);
            long end = Long.parseLong(endTime);
            return end - start;
        } catch (NumberFormatException e) {
            return 0;
        }
    }
    
    /**
     * 验证输入文档的有效性
     */
    public ValidationResult validateInputDocument(CaseDocument caseDocument) {
        ValidationResult result = new ValidationResult();
        List<String> issues = new ArrayList<>();
        
        // 基本字段检查
        if (caseDocument.getCaseId() == null || caseDocument.getCaseId().trim().isEmpty()) {
            issues.add("案件ID不能为空");
        }
        
        if (caseDocument.getPages() == null || caseDocument.getPages().isEmpty()) {
            issues.add("文档页面不能为空");
        }
        
        if (caseDocument.getTotalPages() <= 0) {
            issues.add("总页数必须大于0");
        }
        
        // 页面完整性检查
        if (caseDocument.getPages() != null) {
            for (int i = 0; i < caseDocument.getPages().size(); i++) {
                Page page = caseDocument.getPages().get(i);
                if (page.getPageId() != i + 1) {
                    issues.add("页面ID不连续：期望" + (i + 1) + "，实际" + page.getPageId());
                }
            }
        }
        
        result.setValid(issues.isEmpty());
        result.setIssues(issues);
        
        return result;
    }
    
    /**
     * 获取处理状态
     */
    public ProcessingStatus getProcessingStatus(String caseId) {
        // 实际实现中应该从数据库或缓存中获取
        return ProcessingStatus.COMPLETED;
    }
    
    /**
     * 重新处理失败的案卷
     */
    public CaseProcessingResult reprocessCase(String caseId, CaseDocument caseDocument) {
        System.out.println("重新处理案卷: " + caseId);
        return processCase(caseDocument);
    }
    
    /**
     * 批量处理案卷
     */
    public List<CaseProcessingResult> processBatchCases(List<CaseDocument> caseDocuments) {
        List<CaseProcessingResult> results = new ArrayList<>();
        
        for (CaseDocument caseDoc : caseDocuments) {
            try {
                CaseProcessingResult result = processCase(caseDoc);
                results.add(result);
            } catch (Exception e) {
                CaseProcessingResult errorResult = new CaseProcessingResult();
                errorResult.setCaseId(caseDoc.getCaseId());
                errorResult.setProcessingStatus(ProcessingStatus.FAILED);
                errorResult.setErrorMessage(e.getMessage());
                results.add(errorResult);
            }
        }
        
        return results;
    }
    
    /**
     * 生成处理统计报告
     */
    public BatchProcessingReport generateBatchReport(List<CaseProcessingResult> results) {
        BatchProcessingReport report = new BatchProcessingReport();
        
        int successCount = 0;
        int failedCount = 0;
        long totalDuration = 0;
        
        for (CaseProcessingResult result : results) {
            if (result.isOverallSuccess()) {
                successCount++;
            } else {
                failedCount++;
            }
            totalDuration += result.getProcessingDuration();
        }
        
        report.setTotalCases(results.size());
        report.setSuccessCount(successCount);
        report.setFailedCount(failedCount);
        report.setSuccessRate((double) successCount / results.size());
        report.setAverageProcessingTime(results.isEmpty() ? 0 : totalDuration / results.size());
        
        return report;
    }
}